package com.ys.io.IO流.p3字节输出流;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * 描述: 
 *
 * @author CodeYang
 * @version 2020/12/30 9:21
 */
public class OutputStream的了解与应用01 {


    public static void main(String[] args) {

        //method01();
        //method02();
        //method03();
        //method04();
        //method05();
        //method06();
        //method07();
        method08();

    }
    /**
     * 描述 :try - with -resources 的使用规则
     *场景：定义一个FileOutputStream对象写入数据，将关闭资源的操作使用try with resources完成
     *  * 步骤：
     *  * 1 定义try with resources
     *  * 2 在try()里面创建FileOutputStream对象对象
     *  * 3 调用write(byte[]b)方法写入数据
     *  * AutoCloseable 父接口，作用是自动关闭资源
     *  * |
     *  * Closeable 子接口
     *  * |
     *  * OutputStream 所有输入流的父类，它是一个抽象类
     *  * |
     *  * FileOutputStream 是一个具体类去继承OutputStream
     */
    private static void method08() {
        try (OutputStream fos = new FileOutputStream("b.txt")) {
            fos.write(66);
        }catch (Exception e){
            System.out.println("写入失败");
            e.printStackTrace();
        }
        //   fos在try块定义的所以无法在try外面写入数据，此时程序更加健壮
        //fos.close();
    }

    /**
     * 描述 :
     * 工作中不要在main方法中编写throws关键字，
     * * * 因为main方法已经是最前沿了，无法向上继续声明，这样写只会把异常声明给JVM
     * 所以我们最终有了try - with -resources 这种使用语法与规则
     */
    private static void method07() {
        FileOutputStream fos = null;

        try {
            System.out.println(1/0);  //1 这里是 算术异常 // 后面代码不会执行
            fos = new FileOutputStream("b.txt");
            fos.write("ces".getBytes());
            // 2 所以这里代码不会执行
            /**
             * 不要在try块中去关闭资源，因为一旦close()方法执行之前出现异常，那么FileOutputStream对象占用的内存
             * 无法关闭(释放)
             */
            //fos.close();
        } catch (Exception e) {
            System.out.println("写入文件失败");
            e.printStackTrace();
        }finally {
            // fos在try块中定义的无法在finally块中使用
            // fos.close();
            // Unhandled exception: java.io.IOException
            // close()方法在定义时声明了IOException异常，此时我们没有处理
            try {
                // 关闭资源之前，先判断，条件成立表示fos非空，释放该对象占用的内存空间
                if(null != fos){
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 描述 :
     * 场景：使用FileOutputStream流对象，进行追加写
     *  * 什么叫做追加写？
     *  * 例如：aa.txt文件里面有Hello，我在原来的基础上向a.txt文件追加World。写完之后a.txt文件将变成HelloWorld
     *  * 步骤：1 使用带有两个参数的构造方法创建FileOutputStream对象
     *  *          new FileOutputStream("aa.txt",false);
     *  *          参数1：磁盘文件的路径，此时相对当前工程的路径
     *  *          参数2：追加写的标志位，它是一个boolean类型的参数
     *  *          true：在原有内容的情况下进行追加(不会覆盖文件之前的内容)
     *  *          false：覆盖之前文件的内容
     *  *       2 调用write(byte[] data)方法，将字符串World转换为字节数组(编码)，写入磁盘
     *  *       3 关闭资源
     */
    private static void method06() {
        String str = "Hello";

        try {
            // true表示在原有文件内容的基础上进行追加写，false覆盖之前文件的内容，默认false
            OutputStream fos = new FileOutputStream("b.txt",true);

            fos.write(str.getBytes());
            fos.close();

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 描述 :
     *
     *  * 场景3：写入部分数据 llo
     *  * 步骤：1 创建文件输出流对象，指定路径
     *  *      2 定义一个字符串存储Hello
     *  *      3 调用write(byte[],int,int)方法将He写入磁盘，写入之前先对字符串进行编码
     *  *      4 关闭资源
     */
    private static void method05() {
        String str = "Hello";

        try {
            OutputStream fos = new FileOutputStream("b.txt");

            // fos.write(str.getBytes(),2,3);  数据源 起始点 几个字节
            fos.write(str.getBytes(),2,3);

            // 只要是指向同一个对象,都可以追加 我们可以把OutputStream 作为返回值 这样就可以继续追加写入
            // 关闭FileOutputStream管道，释放 new FileOutputStream("b.txt")对象占用的内存空间
            fos.close();

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     *  武汉尚学堂
     *  * 场景3：如何写入一个单词“Hello” 换行后 继续在写一个Hllo
     *  * 步骤：1 定义一个字符串Hello
     *  *       2 创建文件输出流FileOutputStream对象，并指定路径
     *  *       3 调用write(byte[] data)方法，将字符串Hello转换为字节数组然后写入
     *  *       4 关闭资源
     *   * 如何进行换行？
     *  * window系统下换行符是 \r\n，此时表示回车并且换行
     *  * unix  linux 系统下换行符是 \n
     *  * mac 系统下换行符是 \r
     */

    private static void method04() {
        String str = "测试";

        try {
            OutputStream fos = new FileOutputStream("b.txt");

            //  public void write(byte b[]) 把字节数组写入
            // 字节数组的写入
            fos.write(str.getBytes());
            fos.write("\r\n".getBytes());
            fos.write(str.getBytes());
            // 只要是指向同一个对象,都可以追加 我们可以把OutputStream 作为返回值 这样就可以继续追加写入
            // 关闭FileOutputStream管道，释放 new FileOutputStream("b.txt")对象占用的内存空间
            fos.close();

        }catch (Exception e){
            e.printStackTrace();
        }

    }

    /**
     * * @Author 武汉尚学堂
     *  * 场景3：如何写入一个单词“Hello”
     *  * 步骤：1 定义一个字符串Hello
     *  *       2 创建文件输出流FileOutputStream对象，并指定路径
     *  *       3 调用write(byte[] data)方法，将字符串Hello转换为字节数组然后写入
     *  *       4 关闭资源
     */
    private static void method03() {
        String str = "杨胜";

        try {
            OutputStream fos = new FileOutputStream("b.txt");

            //  public void write(byte b[]) 把字节数组写入
            // 字节数组的写入
            fos.write(str.getBytes());
            fos.write(str.getBytes());
            // 只要是指向同一个对象,都可以追加 我们可以把OutputStream 作为返回值 这样就可以继续追加写入
            // 关闭FileOutputStream管道，释放 new FileOutputStream("b.txt")对象占用的内存空间
            fos.close();

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     *
     * 场景2：创建FIleOutputStream对象，将Java程序的数据写入到磁盘
     * 步骤：1  创建FileOutputStream对象，指定磁盘路径
     *       2 调用write(int)方法写入数据到磁盘中
     *       3 关闭管道
     */
    private static void method02() {
        try {
            OutputStream fos = new FileOutputStream("b.txt");

            fos.write(97);  //a
            fos.write(98);  //b
            fos.write(99);  //c
            // 这里会一次追加,因为指向的同一个对象
            //  fos.write(97);   将对应的int 转为 ASCII 码 一个一个追加写入文件
            // 关闭FileOutputStream管道，释放 new FileOutputStream("b.txt")对象占用的内存空间
            fos.close();

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * * 场景：创建FileOutputStream对象并指定路径
     *  * 步骤：1 使用new关键字创建FileOutputStream对象
     *  *       2 以字符串作为参数指定路径
     *  *       3 打印对象
     *  *  小结：FileOutputStream fos = new FileOutputStream("aa.txt");做了哪些事情？
     *  *  1 创建了一个基于字节的磁盘输出流
     *  *  2 在当前工程下创建了一个aa.txt文件
     *  *  3 将磁盘的aa.txt文件和Java程序进行绑定
     */
    private static void method01() {
        try {
            //  创建 文件字节输出流  如果指定文件不存在会 在URL规则下 创建该文件
            // JAVA 的相对路径 是自己项目工程为起始点 一般常用相对路径
            // 绝对路径还是带盘符的
            //FileOutputStream fos = new FileOutputStream("abc.txt");
            FileOutputStream fos = new FileOutputStream("day_22/abc.txt");

            // java.io.FileOutputStream@1b6d3586
            System.out.println(fos);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }


}

